<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->
<title>VIM 中文帮助: 终端窗口支持</title>
<link rel="stylesheet" href="vim-stylesheet.css" type="text/css" />
<link rel="canonical" href="https://yianwillis.github.io/vimcdoc/doc/terminal.html" />
<script type="text/javascript" src="vimcdoc.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<nav id=banner>
<form action=tags.html target="tag_iframe">
  <input type="text" name="tag" id="tag" placeholder="标签搜索">
</form>
<iframe name="tag_iframe" src=""></iframe>
<a href="help.html">帮助总览</a> &middot;
<hr/>
<a href="quickref.html">快速参考</a> &middot;
<a href="index.html">命令索引</a> &middot;
<a href="eval.html#functions">函数列表</a> &middot;
<a href="quickref.html#option-list">选项列表</a> &middot;
<hr/>
<a href="usr_toc.html">用户手册</a> &middot;
<a href="help.html#reference_toc">参考手册</a> &middot;
</nav>

<header>
<h2>terminal</h2>
</header>
<article id=outer>
<section class=inner>
<b class="vimtag"> <a name="terminal.txt">terminal.txt</a> </b>  适用于 Vim 9.0 版本。   最近更新: 2023年2月


                  <code class="vim">VIM 参考手册    by Bram Moolenaar</code>
                                <code class="vim">译者</code>: Willis


终端窗口支持                            <b class="vimtag"> <a name="terminal">terminal</a> </b> <b class="vimtag"> <a name="terminal-window">terminal-window</a> </b>


终端特性是可选的，要检查你的 Vim 是否带有此特性: 
<code class="example">        echo has('terminal')</code>
如果返回 "1" 就代表拥有此特性。


1. 基本用法                              <a href="terminal.html#terminal-use">terminal-use</a> 
      键入                                       <a href="terminal.html#terminal-typing">terminal-typing</a> 
      大小与色彩                                 <a href="terminal.html#terminal-size-color">terminal-size-color</a> 
      命令语法                                   <a href="terminal.html#:terminal">:terminal</a> 
      调整大小                                   <a href="terminal.html#terminal-resizing">terminal-resizing</a> 
      终端模式                                   <a href="terminal.html#Terminal-mode">Terminal-mode</a> 
      光标风格                                   <a href="terminal.html#terminal-cursor-style">terminal-cursor-style</a> 
      会话                                       <a href="terminal.html#terminal-session">terminal-session</a> 
      特殊键                                     <a href="terminal.html#terminal-special-keys">terminal-special-keys</a> 
      Unix                                       <a href="terminal.html#terminal-unix">terminal-unix</a> 
      MS-Windows                                 <a href="terminal.html#terminal-ms-windows">terminal-ms-windows</a> 
2. 终端函数                              <a href="terminal.html#terminal-function-details">terminal-function-details</a> 
3. 终端通信                              <a href="terminal.html#terminal-communication">terminal-communication</a> 
      Vim 到作业: term_sendkeys()                <a href="terminal.html#terminal-to-job">terminal-to-job</a> 
      作业到 Vim: JSON API                       <a href="terminal.html#terminal-api">terminal-api</a> 
      使用客户-服务器特性                        <a href="terminal.html#terminal-client-server">terminal-client-server</a> 
4. 远程测试                              <a href="terminal.html#terminal-testing">terminal-testing</a> 
5. 屏幕截图比较                          <a href="terminal.html#terminal-diff">terminal-diff</a> 
      编写 Vim 屏幕截图测试                      <a href="terminal.html#terminal-dumptest">terminal-dumptest</a> 
      创建屏幕截图                               <a href="terminal.html#terminal-screendump">terminal-screendump</a> 
      比较屏幕截图                               <a href="terminal.html#terminal-diffscreendump">terminal-diffscreendump</a> 
6. 调试                                  <a href="terminal.html#terminal-debug">terminal-debug</a> 
      启动                                       <a href="terminal.html#termdebug-starting">termdebug-starting</a> 
      示例会话                                   <a href="terminal.html#termdebug-example">termdebug-example</a> 
      代码中步进                                 <a href="terminal.html#termdebug-stepping">termdebug-stepping</a> 
      检视变量                                   <a href="terminal.html#termdebug-variables">termdebug-variables</a> 
      其它命令                                   <a href="terminal.html#termdebug-commands">termdebug-commands</a> 
      事件                                       <a href="terminal.html#termdebug-events">termdebug-events</a> 
      提示模式                                   <a href="terminal.html#termdebug-prompt">termdebug-prompt</a> 
      通信                                       <a href="terminal.html#termdebug-communication">termdebug-communication</a> 
      定制                                       <a href="terminal.html#termdebug-customizing">termdebug-customizing</a> 

<code class="notvi">{仅当编译时加入  <a href="various.html#+terminal">+terminal</a>  特性才有效}</code>
终端特性需要  <a href="various.html#+job">+job</a>  和  <a href="various.html#+channel">+channel</a>  特性的支持。

</section><hr class="doubleline" /><section class=inner>
<h4>1. 基本用法                                             <b class="vimtag"> <a name="terminal-use">terminal-use</a> </b></h4>
本特性用于在 Vim 窗口中运行终端模拟器。终端模拟器启动时可以连接作业。例如，运
行外壳程序: 
<code class="example">     :term bash</code>
<code class="example"></code>
或运行编译命令: 
<code class="example">     :term make myprogram</code>
<code class="example"></code>
作业和 Vim 异步运行，窗口会刷新以显示作业的输出，同时在其它窗口上进行编辑。


<code class="section">键入 </code>
                                                        <b class="vimtag"> <a name="terminal-typing">terminal-typing</a> </b>
键盘的焦点在终端窗口时，输入的键会发送给其中的作业。可能的话使用 pty。在终端窗
口之外点击把键盘焦点移到别处。

                                                <b class="vimtag"> <a name="t_CTRL-W_CTRL-W">t_CTRL-W_CTRL-W</a> </b> <b class="vimtag"> <a name="t_CTRL-W_:">t_CTRL-W_:</a> </b>
<code class="keystroke">CTRL-W</code> 可用来在窗口间切换和执行其它 <code class="keystroke">CTRL-W</code> 命令，如:
        <code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-W</code>   移动焦点到下个窗口
        <code class="keystroke">CTRL-W</code> :        输入 Ex 命令
更多命令见  <a href="index.html#CTRL-W">CTRL-W</a> 。

终端窗口特有的映射:                             <b class="vimtag"> <a name="t_CTRL-W_.">t_CTRL-W_.</a> </b>  <b class="vimtag"> <a name="t_CTRL-W_N">t_CTRL-W_N</a> </b>
        <code class="keystroke">CTRL-W</code> .        给终端中的作业发送 <code class="keystroke">CTRL-W</code>
        <code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-\</code>   给终端中的作业发送 <code class="keystroke">CTRL-\</code>
        <code class="keystroke">CTRL-W</code> N        切换到终端普通模式，见  <a href="terminal.html#Terminal-mode">Terminal-mode</a> 
        <code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-N</code>   切换到终端普通模式，见  <a href="terminal.html#Terminal-mode">Terminal-mode</a> 
        <code class="keystroke">CTRL-W</code> " <code class="special">{reg}</code>  粘贴寄存器 <code class="special">{reg}</code>                <b class="vimtag"> <a name="t_CTRL-W_quote">t_CTRL-W_quote</a> </b>
                        也适用于 = 寄存器，插入表达式计算的结果。
        <code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-C</code>   结束作业，见下  <a href="terminal.html#t_CTRL-W_CTRL-C">t_CTRL-W_CTRL-C</a> 
        <code class="keystroke">CTRL-W</code> gt       转到下个标签页，相当于  <a href="tabpage.html#gt">gt</a>              <b class="vimtag"> <a name="t_CTRL-W_gt">t_CTRL-W_gt</a> </b>
        <code class="keystroke">CTRL-W</code> gT       转到上个标签页，相当于  <a href="tabpage.html#gT">gT</a>              <b class="vimtag"> <a name="t_CTRL-W_gT">t_CTRL-W_gT</a> </b>

另见选项 <a href="options.html#'termwinkey'">'termwinkey'</a>，指定 <code class="keystroke">CTRL-W</code> 的替代键，和 <code class="keystroke">CTRL-W</code> 的用法相同。不过，输入
<a href="options.html#'termwinkey'">'termwinkey'</a> 两次会给作业发送 <a href="options.html#'termwinkey'">'termwinkey'</a>。例如:
        <a href="options.html#'termwinkey'">'termwinkey'</a> <code class="keystroke">CTRL-W</code>    移动焦点到下个窗口
        <a href="options.html#'termwinkey'">'termwinkey'</a> :         输入 Ex 命令
        <a href="options.html#'termwinkey'">'termwinkey'</a> <a href="options.html#'termwinkey'">'termwinkey'</a> 给终端中的作业发送 <a href="options.html#'termwinkey'">'termwinkey'</a>
        <a href="options.html#'termwinkey'">'termwinkey'</a> .         给终端中的作业发送 <a href="options.html#'termwinkey'">'termwinkey'</a>
        <a href="options.html#'termwinkey'">'termwinkey'</a> <code class="keystroke">CTRL-\</code>    给终端中的作业发送 <code class="keystroke">CTRL-\</code>
        <a href="options.html#'termwinkey'">'termwinkey'</a> N         切换到终端普通模式，见下
        <a href="options.html#'termwinkey'">'termwinkey'</a> <code class="keystroke">CTRL-N</code>    同 <code class="keystroke">CTRL-W</code> N  <a href="terminal.html#t_CTRL-W_N">t_CTRL-W_N</a> 
        <a href="options.html#'termwinkey'">'termwinkey'</a> <code class="keystroke">CTRL-C</code>    同 <code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-C</code>  <a href="terminal.html#t_CTRL-W_CTRL-C">t_CTRL-W_CTRL-C</a> 
                                                        <b class="vimtag"> <a name="t_CTRL-\_CTRL-N">t_CTRL-\_CTRL-N</a> </b>
特殊键组合 <code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-N</code> 可用于切换到普通模式，其它模式下也都如此。
                                                        <b class="vimtag"> <a name="t_CTRL-W_CTRL-C">t_CTRL-W_CTRL-C</a> </b>
<code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-C</code> 可可用强制结束作业。MS-Windows 上 <code class="keystroke">CTRL-Break</code> 也会杀掉作业。

直接按 <code class="keystroke">CTRL-C</code> 的效果取决于 pty 的相应配置。简单命令会导致 SIGINT 发送给作业，
结果是中止作业。其它命令可能会忽略 SIGINT 或自行处理 <code class="keystroke">CTRL-C</code> (Vim 就是如此)。

要改变终端模式的映射所用的键，请见  <a href="map.html#:tmap">:tmap</a> 。和其它映射的定义类似，但适用于给终
端中运行的作业发送的键。例如，要使 F1 切换到终端普通模式: 
<code class="example">   tnoremap &lt;F1&gt; &lt;C-W&gt;N</code>
可以用 Esc，但务须保证不影响其它的键 (光标键以 Esc 开始，所以可能会受影响)，这
可能只能用于 GUI: 
<code class="example">   tnoremap &lt;Esc&gt; &lt;C-W&gt;N</code>
<code class="example">   set notimeout ttimeout timeoutlen=100</code>
<code class="example"></code>
类似于终端模式映射，也可建立菜单，但只能用  <a href="gui.html#:tlmenu">:tlmenu</a>  而不是  <a href="gui.html#:tmenu">:tmenu</a> 。

                                                        <b class="vimtag"> <a name="options-in-terminal">options-in-terminal</a> </b>
打开终端窗口并设置其 <a href="options.html#'buftype'">'buftype'</a> 为 "terminal" 后，激活  <a href="autocmd.html#TerminalWinOpen">TerminalWinOpen</a>  自动命
令。这样便可以设置为其窗口和缓冲区特定的选项。例如: 
<code class="example">   au TerminalWinOpen * setlocal bufhidden=hide</code>
这只适用于未隐藏的终端。

要同时支持隐藏和非隐藏终端，可用以下设置，它适用于缓冲区局部和窗口局部选项: 
<code class="example">   au TerminalWinOpen,BufWinEnter * if &amp;buftype == 'terminal'</code>
<code class="example">        \ | setlocal bufhidden=hide colorcolumn=123</code>
<code class="example">        \ | endif</code>
<code class="note">注意</code>对隐藏终端而言，直到终端不再隐藏时才会设置以上选项。

也有  <a href="autocmd.html#TerminalOpen">TerminalOpen</a>  事件，请记住隐藏终端也触发此事件，此时当前窗口和缓冲区未必
用于新终端。
这里可能需要 <code class="special">&lt;abuf&gt;</code>，它被设为终端缓冲区。例如: 
<code class="example">    au TerminalOpen * call setbufvar(expand('&lt;abuf&gt;')-&gt;str2nr(),</code>
<code class="example">            \ '&amp;termwinscroll', 1000)</code>
对窗口局部选项而言，选项的设置要延迟到终端窗口创建时 (只适用于隐藏终端): 
<code class="example">    au TerminalOpen * exe printf(</code>
<code class="example">        \    'au BufWinEnter &lt;buffer=%d&gt; ++once setlocal colorcolumn=%d',</code>
<code class="example">        \       expand('&lt;abuf&gt;')-&gt;str2nr(), 123)</code>
非隐藏终端可用  <a href="autocmd.html#TerminalWinOpen">TerminalWinOpen</a> 。

鼠标事件 (点击和拖曳) 会传给终端。而鼠标移动事件只有 Vim 自身接收到时才会传
递。对终端而言，这意味着 <a href="options.html#'balloonevalterm'">'balloonevalterm'</a> 打开。


<code class="section">大小与色彩 </code>
                                                        <b class="vimtag"> <a name="terminal-size-color">terminal-size-color</a> </b>
关于控制终端窗口的大小，见 <a href="options.html#'termwinsize'">'termwinsize'</a> 选项。
(TODO: 终端超出窗口大小时的滚动)

终端中运行的作业可以改变色彩。缺省前景和背景色来自 Vim 的 Normal 高亮组。

对色彩终端而言，<a href="options.html#'background'">'background'</a> 选项用于决定终端窗口以白色或是黑色背景开始。

要使用其它颜色，使用 Terminal 高亮组，例如: 
<code class="example">    hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue</code>
可用  <a href="terminal.html#term_start()">term_start()</a>  的 "term_highlight" 选项来指定另一个组名来代替 Terminal。

                                                        <b class="vimtag"> <a name="g:terminal_ansi_colors">g:terminal_ansi_colors</a> </b>
GUI 模式或使用 <a href="options.html#'termguicolors'">'termguicolors'</a> 时，新的终端窗口缺省使用的 16 种 ANSI 颜色可通
过  <a href="terminal.html#g:terminal_ansi_colors">g:terminal_ansi_colors</a>  设置，它应是 16 种色彩名或十六制色彩代码的列表，类
似于  <a href="syntax.html#highlight-guifg">highlight-guifg</a>  接受的格式。如果不使用 GUI 颜色，终端窗口总是使用下层终
端的 16 种 ANSI 色。
使用  <a href="terminal.html#term_start()">term_start()</a>  时，可用 "ansi_colors" 选项设置色彩。
 <a href="terminal.html#term_setansicolors()">term_setansicolors()</a>  函数可用来改变颜色，而  <a href="terminal.html#term_getansicolors()">term_getansicolors()</a>  可获取当
前使用的颜色。


<code class="section">命令语法 </code>

:<code class="special">[range]</code>ter[minal] <code class="special">[options]</code> <code class="special">[command]</code>                  <b class="vimtag"> <a name=":ter">:ter</a> </b> <b class="vimtag"> <a name=":terminal">:terminal</a> </b>
                        打开新终端窗口。

                        给出 <code class="special">[command]</code> 时，把它作为作业运行，并连接其输入和输
                        出到终端上。
                        如果没有给出 <code class="special">[command]</code>，使用 <a href="options.html#'shell'">'shell'</a> 选项值。
                        如果 <code class="special">[command]</code> 为 NONE，不启动作业，但终端的 pty 可被
                        gdb 这样的命令使用。

                        如果没有给出 <code class="special">[command]</code>，缺省行为是外壳退出时关闭终端。
                        可以用 ++noclose 参数改变此行为。
                        给出 <code class="special">[command]</code> 时，缺省行为是保持终端打开在终端普通模
                        式下。可以用 ++close 参数改变此行为。

                        不能后跟 Vim 命令，任何的 | 都会包含在 <code class="special">[command]</code> 中。
                        如果必须要在同一行上后跟 Vim 命令，可用  <a href="eval.html#:execute">:execute</a>  。

                        建立新缓冲区，名字使用 <code class="special">[command]</code> 或 <a href="options.html#'shell'">'shell'</a> 再加上前缀
                        "!"。如果带此名的缓冲区已存在，加一个括起的数值。比
                        如，如果 "gdb" 存在 (<code class="vim">译者注</code>: 似应为 "!gdb")，第二个终
                        端缓冲区会用名字 "!gdb (1)" 。

                        如果给出 <code class="special">[range]</code>，使用给定行的范围作为作业的输入。此时
                        终端窗口不接受键盘输入。MS-Windows 请见下面的 ++eof 参
                        数。

                                                <b class="vimtag"> <a name="term++close">term++close</a> </b> <b class="vimtag"> <a name="term++open">term++open</a> </b>
                        支持的 <code class="special">[options]</code> 有:
                        ++close         作业终止时自动关闭终端窗口。
                                         <a href="terminal.html#terminal-close">terminal-close</a> 
                        ++noclose       作业终止时 <code class="emphasis">不</code> 自动关闭终端窗口。
                        ++open          作业终止时如果没有窗口显示它，会打开窗
                                        口。
                                        <code class="note">注意</code> 这会打断正常的操作。
                                最后出现的 ++close、 ++noclose 和 ++open 才起
                                作用并否决之前的参数。

                        ++curwin        在当前窗口打开终端，不分割当前窗口。如
                                        果当前缓冲区不能  <a href="editing.html#abandon">abandon</a>  则失败。
                        ++hidden        在隐藏缓冲区打开终端，不使用窗口。
                        ++norestore     不把此终端窗口加到会话文件中。
                        ++shell         不直接执行 <code class="special">{command}</code>，而使用外壳，就像
                                         <code class="badlink">:!command</code>  那样        <b class="vimtag"> <a name="E279">E279</a> </b>
                                        <code class="notvi">{仅能用于 Unix 和 MS-Windows}</code>
                        ++kill=<code class="special">{how}</code>    关闭终端窗口的尝试使用 <code class="special">{how}</code> 信号杀死
                                        作业。相关值见  <a href="terminal.html#term_setkill()">term_setkill()</a> 。
                        ++rows=<code class="special">{height}</code> 使用 <code class="special">{height}</code> 作为终端窗口高度。如果终
                                        端使用整个 Vim 的高度 (终端窗口上下没
                                        有其它窗口)，有必要时会减少命令行高
                                        度。
                        ++cols=<code class="special">{width}</code>  使用 <code class="special">{width}</code> 作为终端窗口宽度。如果 终
                                        端使用整个 Vim 的宽度 (终端窗口左右没
                                        有其它窗口)，忽略此值。
                        ++eof=<code class="special">{text}</code>    使用 <code class="special">[range]</code> 时: 写完最后一行后发送的
                                        文本。之后附加 CR。MS-Windows 缺省发送
                                        的是 <code class="keystroke">CTRL-D</code>。
                                        例如，外壳用 "++eof=exit" 而 Python 用
                                        "++eof=exit()"。特殊代码可以用  <a href="map.html#:map">:map</a> 
                                        类似的用法，如 "<code class="special">&lt;C-Z&gt;</code>" 代表 <code class="keystroke">CTRL-Z</code>。
                        ++type=<code class="special">{pty}</code>    (仅 MS-Windows): 使用 <code class="special">{pty}</code> 作为虚拟控
                                        制台。相关值见 <a href="options.html#'termwintype'">'termwintype'</a>。
                        ++api=<code class="special">{expr}</code>    允许以 <code class="special">{expr}</code> 开始的函数名作为
                                         <a href="terminal.html#terminal-api">terminal-api</a>  函数调用。如果 <code class="special">{expr}</code>
                                        为空不能调用函数。

                        想要更多选项，可用  <a href="terminal.html#term_start()">term_start()</a>  函数。
                        要垂直分割窗口，用: 
<code class="example">                                :vertical terminal</code>
                        或更简短: 
<code class="example">                                :vert ter</code>
<code class="example"></code>
和终端相关联的缓冲区被强制卸载或真正删除时，杀死作业，相当于调用
`job_stop(job, "kill")`。
正常关闭窗口会给出  <a href="terminal.html#E947">E947</a> 。如果用 "++kill=<code class="special">{how}</code>" 或  <a href="terminal.html#term_setkill()">term_setkill()</a>  给出杀死
进程的方法，则窗口关闭时使用该方法杀掉或中断作业。例如: 
<code class="example">        :term ++kill=term tail -f /tmp/log</code>
<code class="example"></code>
只要作业还在运行，窗口把它当做包含修改过的缓冲区。用 `<code class="keystroke">CTRL-W</code> :quit` 试图关闭窗
口会失败。如果用 `<code class="keystroke">CTRL-W</code> :quit!`，作业会结束。但窗口中的文本会丢失。缓冲区被删
除。用 `<code class="keystroke">CTRL-W</code> :bunload!` 则缓冲区会保留但为空。

用 `<code class="keystroke">CTRL-W</code> :close` 试图关闭窗口也会失败。用 `<code class="keystroke">CTRL-W</code> :close!` 会关闭窗口并隐藏
缓冲区。

用 `<code class="keystroke">CTRL-W</code> :hide` 关闭终端窗口并隐藏缓冲区，但作业继续执行。 <a href="windows.html#:buffer">:buffer</a>  命令可用
来把当前窗口变成终端窗口。如果有未保存的改变，这会失败，但和平常一样用 ! 可以
强制进行。

                                                        <b class="vimtag"> <a name="terminal-close">terminal-close</a> </b>
如果关闭了终端窗口，比如外壳退出且使用了 "++close" 参数时，且此窗口是 Vim 最后
一个正常的窗口，Vim 会退出。这类似于普通窗口中用了  <a href="editing.html#:quit">:quit</a> 。帮助和预览窗口不计
在内。

要不打开窗口在后台运行作业，完成后再打开窗口，可以这样使用选项: 
<code class="example">        :term ++hidden ++open make</code>
<code class="note">注意</code> 窗口会在意想不到的时候打开，可能会中断你正在做的事情。

                                                        <b class="vimtag"> <a name="E947">E947</a> </b> <b class="vimtag"> <a name="E948">E948</a> </b>
只要作业还在运行，缓冲区被认为是已修改，Vim 不能随便退出，见  <a href="editing.html#abandon">abandon</a> 。

作业结束且缓冲区没有发生改动时: 关闭窗口会真正删除缓冲区。

在终端缓冲区可以改动之前，<a href="options.html#'modifiable'">'modifiable'</a> 选项必须置位。这只有在作业结束时才有可
能。此时，第一个改动会把缓冲区变成正常的缓冲区并删除高亮。你也许要用  <a href="editing.html#:file">:file</a> 
来改变缓冲区名以便写入文件，不然缓冲区名仍然对应着命令。


<code class="section">调整大小 </code>
                                                        <b class="vimtag"> <a name="terminal-resizing">terminal-resizing</a> </b>
终端大小处于以下三种模式之一:

1. <a href="options.html#'termwinsize'">'termwinsize'</a> 选项为空: 终端大小跟随窗口大小。最小尺寸是 2 行屏幕行，每行
   10 个单元格。

2. <a href="options.html#'termwinsize'">'termwinsize'</a> 选项形如 "rows*cols"，其中 "rows" 为屏幕行的最少数目，而
   "cols" 是单元格的最少数目。

3. <a href="options.html#'termwinsize'">'termwinsize'</a> 选项形如 "rowsXcols" (其中 x 可以大小写)。终端大小固定为指定
   的屏幕行和单元格数。如果窗口较之为大，会有多出来的不可用的空白空间。

如果窗口小于终端大小，终端只有部分可见 (左下部分)。

 <a href="terminal.html#term_getsize()">term_getsize()</a>  函数可用于获取终端的当前大小。 <a href="terminal.html#term_setsize()">term_setsize()</a>  只可用于前两种
模式，不能用于 <a href="options.html#'termwinsize'">'termwinsize'</a> 为 "rowsXcols" 的情况。


<code class="section">终端作业和终端普通模式 </code>
                                                <b class="vimtag"> <a name="Terminal-mode">Terminal-mode</a> </b> <b class="vimtag"> <a name="Terminal-Job">Terminal-Job</a> </b>
作业运行时终端的内容受作业控制。这也包括光标的位置。输入的键发送给作业。终端的
内容可随时改变。这称为终端作业模式。

<code class="keystroke">CTRL-W</code> N (或 <a href="options.html#'termwinkey'">'termwinkey'</a> N) 切换到终端普通模式。此时，终端窗口内容由 Vim 控
制，作业的输出被暂停。<code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-N</code> 的效果相同。

终端作业模式适用  <a href="map.html#:tmap">:tmap</a>  映射。tmap 不用于  <a href="terminal.html#term_sendkeys()">term_sendkeys()</a>  发送的键，但会用
于来自  <a href="builtin.html#feedkeys()">feedkeys()</a>  的键。

从终端作业模式不能进入插入模式。

                                                <b class="vimtag"> <a name="Terminal-Normal">Terminal-Normal</a> </b> <b class="vimtag"> <a name="E946">E946</a> </b>
终端普通模式里可用通常的 Vim 命令来移动光标、可视标记文本、抽出文本等等。但不
能修改缓冲区的内容。启动插入模式的命令如 'i' 和 'a' 等会回到终端作业模式。窗口
会刷新以显示终端的内容。 <a href="insert.html#:startinsert">:startinsert</a>  无效。

终端普通模式下状态行和窗口标题会显示 "(Terminal)"。如果作业已结束且在终端普通
模式下，则为 "(Terminal-finished)"。

终端中作业输出的行，包括滚过了屏幕顶部的内容，会被记住且在终端普通模式中可见。
行数受 <a href="options.html#'termwinscroll'">'termwinscroll'</a> 选项限制。超过此限制时，滚动行的前 10% 被删除且丢失。


<code class="section">光标风格 </code>
                                                        <b class="vimtag"> <a name="terminal-cursor-style">terminal-cursor-style</a> </b>
缺省终端窗口使用不闪烁的块状光标。正常的 xterm 转义序列可用于改变闪烁状态和形
状。一旦焦点离开终端窗口，Vim 会恢复原有的光标。

一个例外是当 xterm 启动时带 "-bc" 参数或通过别的方式使光标闪烁的时候。这实际意
味着反转闪烁标志位。因为 Vim 没法检测这一点，终端窗口的光标闪烁也被反转。


<code class="section">会话 </code>
                                                        <b class="vimtag"> <a name="terminal-session">terminal-session</a> </b>
如有可能且用户需要的话，使用会话文件可以恢复终端窗口。

如果 <a href="options.html#'sessionoptions'">'sessionoptions'</a> 删除了 "terminal"，不恢复终端窗口。

如果终端中运行的作业已经结束，不恢复其窗口。

如果终端可以恢复，会再次使用曾经用来打开它的命令。要改变之，使用
 <a href="terminal.html#term_setrestore()">term_setrestore()</a>  函数。把相应的命令设为 "NONE"，也可用这个函数来选择性不恢
复特定的终端。


<code class="section">特殊键</code>
                                                        <b class="vimtag"> <a name="terminal-special-keys">terminal-special-keys</a> </b>
因为终端模拟器模拟的是 xterm 终端，终端窗口只能接收 Vim 和 xterm 都能识别的转
义序列。要想给终端中运行的作业传递其它转义序列，需要设置转发。示例: 
<code class="example">        tmap &lt;expr&gt; &lt;Esc&gt;]b SendToTerm("\&lt;Esc&gt;]b")</code>
<code class="example">        func SendToTerm(what)</code>
<code class="example">          call term_sendkeys('', a:what)</code>
<code class="example">          return ''</code>
<code class="example">        endfunc</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">Unix </code>
                                                        <b class="vimtag"> <a name="terminal-unix">terminal-unix</a> </b>
Unix 上使用 pty 来运行所有类型的命令。包含在终端上运行 Vim 自身！这可用调试，
见下。

可用环境变量为运行的作业传递信息:
    TERM                终端名，来自 <a href="options.html#'term'">'term'</a> 选项或 GUI 里的 $TERM；如果不以
                        "xterm" 开头的话，回退到 "xterm"
    ROWS                终端初始行数
    LINES               同 ROWS
    COLUMNS             终端初始列数
    COLORS              颜色数，<a href="term.html#'t_Co'">'t_Co'</a> (GUI 里是 256*256*256)
    VIM_SERVERNAME      v:servername
    VIM_TERMINAL        v:version


<code class="section">MS-Windows </code>
                                                        <b class="vimtag"> <a name="terminal-ms-windows">terminal-ms-windows</a> </b>
MS-Windows 上使用 winpty 来运行所有类型的命令。显然，必须是终端上运行的命令，
不能打开它们自己的窗口。

需要来自 winpty 的两个文件:

    winpty.dll
    winpty-agent.exe

可以从下面页面下载它们:

    <a href="https://github.com/rprichard/winpty">https://github.com/rprichard/winpty</a>

只有把它们放在你的 PATH 路径某处就行了。有必要的话，设置 <a href="options.html#'winptydll'">'winptydll'</a> 选项指向
正确的文件。如果同时有 32 位和 64 位版本，把它们分别换名为 winpty32.dll 和
winpty64.dll 来对应 Vim 编译时的用法。

                                                        <b class="vimtag"> <a name="ConPTY">ConPTY</a> </b> <b class="vimtag"> <a name="E982">E982</a> </b>
在更新的 MS-Windows 10 版本 (从 "October 2018 Update" 开始)，不再需要 winpty。
在这些版本中， <a href="terminal.html#:terminal">:terminal</a>  会使用 Windows 的内建终端应用寄主支持，"ConPTY"。
使用 ConPTY 时，可能有二义性宽度字符渲染的痕迹。如果这方面遇到问题，安装
"winpty" 。除非 ConPTY 的问题修正为止，还是建议 "winpty"。

可用环境变量为运行的作业传递信息:
    VIM_SERVERNAME      v:servername


</section><hr class="doubleline" /><section class=inner>
<h4>2. 终端函数                                      <b class="vimtag"> <a name="terminal-function-details">terminal-function-details</a> </b></h4>
                                                        <b class="vimtag"> <a name="term_dumpdiff()">term_dumpdiff()</a> </b>
term_dumpdiff(<code class="special">{filename}</code>, <code class="special">{filename}</code> [, <code class="special">{options}</code>])
                打开新窗口，显示两个文件的差异。必须是  <a href="terminal.html#term_dumpwrite()">term_dumpwrite()</a> 
                创建的文件。
                返回缓冲区号，如果比较失败返回零。
                另见  <a href="terminal.html#terminal-diff">terminal-diff</a> 。
                <code class="note">备注</code>: 还未支持双宽度字符。

                缓冲区顶部包含第一个文件的内容，底部则包含第二个文件的内容。中
                间部分显示差异。部分之间以等号线行分隔。

                如果给出 <code class="special">{options}</code> 参数，必须是包含以下元素的字典:
                   "term_name"       用作缓冲区名，缺省是首个文件名。
                   "term_rows"       终端用的垂直空间，缺省是 <a href="options.html#'termwinsize'">'termwinsize'</a>，
                                     但顾及最小尺寸
                   "term_cols"       终端用的水平空间，缺省是 <a href="options.html#'termwinsize'">'termwinsize'</a>，
                                     但顾及最小尺寸
                   "vertical"        垂直分割窗口
                   "curwin"          使用当前窗口，不分割窗口；如果不能
                                      <a href="editing.html#abandon">abandon</a>  当前缓冲区，则报错
                   "bufnr"           不创建新缓冲区，使用已有缓冲区 "bufnr"。
                                     此缓冲区必须是之前用 term_dumpdiff() 或
                                     term_dumpload() 建立的，且在窗口中可见。
                   "norestore"       不把终端窗口加入会话文件

                中间部分的每个字符指示某个差异。如果有多个差异只使用下面列表的
                第一个选择:
                        X       不同字符
                        w       不同宽度
                        f       不同前景色
                        b       不同后景色
                        a       不同属性
                        +       第一个文件缺失的位置
                        -       第二个文件缺失的位置
                        &gt;       在第一个文件而不在第二个文件的光标位置
                        &lt;       在第二个文件而不在第一个文件的光标位置

                "s" 键交换顶部和底部，以方便发现不同之处。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetFilename()-&gt;term_dumpdiff(otherfile)</code>

                                                        <b class="vimtag"> <a name="term_dumpload()">term_dumpload()</a> </b>
term_dumpload(<code class="special">{filename}</code> [, <code class="special">{options}</code>])
                打开新窗口显示 <code class="special">{filename}</code> 内容。必须是  <a href="terminal.html#term_dumpwrite()">term_dumpwrite()</a>  创建
                的文件。
                返回缓冲区号，如果失败返回零。
                另见  <a href="terminal.html#terminal-diff">terminal-diff</a> 。

                <code class="special">{options}</code> 可见  <a href="terminal.html#term_dumpdiff()">term_dumpdiff()</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetFilename()-&gt;term_dumpload()</code>

                                                        <b class="vimtag"> <a name="term_dumpwrite()">term_dumpwrite()</a> </b>
term_dumpwrite(<code class="special">{buf}</code>, <code class="special">{filename}</code> [, <code class="special">{options}</code>])
                把 <code class="special">{buf}</code> 的终端屏幕的内容保存到 <code class="special">{filename}</code> 文件里。使用的格式
                可用于  <a href="terminal.html#term_dumpload()">term_dumpload()</a>  和  <a href="terminal.html#term_dumpdiff()">term_dumpdiff()</a> 。
                如果终端中的作业已经结束，报错。 <b class="vimtag"> <a name="E958">E958</a> </b>
                如果 <code class="special">{filename}</code> 已存在，报错。 <b class="vimtag"> <a name="E953">E953</a> </b>
                另见  <a href="terminal.html#terminal-diff">terminal-diff</a> 。

                <code class="special">{options}</code> 是包含以下可选项目的字典:
                        "rows"          保存的最大行数
                        "columns"       保存的最大列数

                也可用作  <a href="eval.html#method">method</a> ，基用于文件名: 
<code class="example">                        GetFilename()-&gt;term_dumpwrite(bufnr)</code>
<code class="example"></code>
term_getaltscreen(<code class="special">{buf}</code>)                                <b class="vimtag"> <a name="term_getaltscreen()">term_getaltscreen()</a> </b>
                如果 <code class="special">{buf}</code> 的终端使用轮换屏幕，则返回 1。
                <code class="special">{buf}</code> 的用法同  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getaltscreen()</code>
<code class="example"></code>
<code class="example"></code>
term_getansicolors(<code class="special">{buf}</code>)                               <b class="vimtag"> <a name="term_getansicolors()">term_getansicolors()</a> </b>
                获得终端 <code class="special">{buf}</code> 的 ANSI 色彩调色板。
                返回 16 个元素的列表，每个元素是代表颜色的字符串，使用十六进制
                "#rrggbb" 格式。
                另见  <a href="terminal.html#term_setansicolors()">term_setansicolors()</a>  和  <a href="terminal.html#g:terminal_ansi_colors">g:terminal_ansi_colors</a> 。
                如果两者都不用，返回缺省颜色。

                <code class="special">{buf}</code> 的用法同  <a href="terminal.html#term_getsize()">term_getsize()</a> 。如果缓冲区不存在或不是终端窗
                口，返回空列表。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getansicolors()</code>
<code class="example"></code>
                <code class="notvi">{仅当编译时打开 GUI 和/或  <a href="various.html#+termguicolors">+termguicolors</a>  特性时才有效}</code>

term_getattr(<code class="special">{attr}</code>, <code class="special">{what}</code>)                            <b class="vimtag"> <a name="term_getattr()">term_getattr()</a> </b>
                给出一个由 term_scrape() 的 "attr" 项目返回的 <code class="special">{attr}</code>，返回它是
                否打开了 <code class="special">{what}</code>。<code class="special">{what}</code> 是以下之一:
                        bold (粗体)
                        italic (斜体)
                        underline (带下划线)
                        strike (带删除线)
                        reverse (反相)

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetAttr()-&gt;term_getattr()</code>
<code class="example"></code>
<code class="example"></code>
term_getcursor(<code class="special">{buf}</code>)                                   <b class="vimtag"> <a name="term_getcursor()">term_getcursor()</a> </b>
                获取 <code class="special">{buf}</code> 终端所在的光标位置。返回两个数值和一个字典组成的列
                表: [row, col, dict]。

                "row" 和 "col" 从 1 开始，比如，首个屏幕单元格在第一列第一行。
                这是终端本身所在的光标位置，不是 Vim 窗口的光标位置。

                "dict" 可有以下成员:
                   "visible"    一如果光标可见，零如果光标隐藏。
                   "blink"      一如果光标闪烁，零如果光标不闪烁。
                   "shape"      块状光标为 1，下划线为 2，垂直线为 3。
                   "color"      光标的颜色，例如 "green"

                <code class="special">{buf}</code> 必须是对应终端窗口的缓冲区号。如果该缓冲区不存在或不是终
                端窗口，返回空列表。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getcursor()</code>
<code class="example"></code>
term_getjob(<code class="special">{buf}</code>)                                      <b class="vimtag"> <a name="term_getjob()">term_getjob()</a> </b>
                获取终端窗口 <code class="special">{buf}</code> 相关联的作业。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。
                没有相关作业时返回  <a href="eval.html#v:null">v:null</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getjob()</code>
<code class="example"></code>
<code class="example"></code>
term_getline(<code class="special">{buf}</code>, <code class="special">{row}</code>)                              <b class="vimtag"> <a name="term_getline()">term_getline()</a> </b>
                获取终端窗口 <code class="special">{buf}</code> 的文本行。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                首行的 <code class="special">{row}</code> 数为一。<code class="special">{row}</code> 为 "." 时使用光标所在行。<code class="special">{row}</code> 非法
                时返回空串。

                要获取每个字符的属性可用  <a href="terminal.html#term_scrape()">term_scrape()</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getline(row)</code>
<code class="example"></code>
<code class="example"></code>
term_getscrolled(<code class="special">{buf}</code>)                                 <b class="vimtag"> <a name="term_getscrolled()">term_getscrolled()</a> </b>
                返回终端 <code class="special">{buf}</code> 滚动过顶部的行数。也就是  <a href="terminal.html#term_getline()">term_getline()</a>  和
                 <a href="builtin.html#getline()">getline()</a>  所用行号的相对偏移，亦即: 
<code class="example">                        term_getline(buf, N)</code>
                等价于: 
<code class="example">                        getline(N + term_getscrolled(buf))</code>
                (如果该行存在)。

                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getscrolled()</code>
<code class="example"></code>
<code class="example"></code>
term_getsize(<code class="special">{buf}</code>)                                     <b class="vimtag"> <a name="term_getsize()">term_getsize()</a> </b>
                返回终端 <code class="special">{buf}</code> 的大小，即两个数值组成的列表: [rows, cols]。
                这是终端的大小，不是包含终端窗口的大小。

                <code class="special">{buf}</code> 必须是对应终端窗口的缓冲区号。空串代表当前缓冲区。如果该
                缓冲区不存在或不是终端窗口，返回空列表。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getsize()</code>
<code class="example"></code>
<code class="example"></code>
term_getstatus(<code class="special">{buf}</code>)                                   <b class="vimtag"> <a name="term_getstatus()">term_getstatus()</a> </b>
                返回终端 <code class="special">{buf}</code> 的状态，即逗号分隔的项目列表组成的字符串:
                        running         作业在运行中
                        finished        作业已完成
                        normal          在终端普通模式中
                "running" 或 "finished" 两者必有其一。

                <code class="special">{buf}</code> 必须是对应终端窗口的缓冲区号。如果该缓冲区不存在或不是终
                端窗口，返回空串。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_getstatus()</code>
<code class="example"></code>
<code class="example"></code>
term_gettitle(<code class="special">{buf}</code>)                                    <b class="vimtag"> <a name="term_gettitle()">term_gettitle()</a> </b>
                获取终端 <code class="special">{buf}</code> 的标题。这是终端中的作业设置的标题。

                <code class="special">{buf}</code> 必须是对应终端窗口的缓冲区号。如果该缓冲区不存在或不是终
                端窗口，返回空串。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_gettitle()</code>
<code class="example"></code>
<code class="example"></code>
term_gettty(<code class="special">{buf}</code> [, <code class="special">{input}</code>])                          <b class="vimtag"> <a name="term_gettty()">term_gettty()</a> </b>
                获取终端窗口 <code class="special">{buf}</code> 相关联的控制终端的名字。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                <code class="special">{input}</code> 省略或为 0 时，返回用于写入的终端名 (stdout)。<code class="special">{input}</code>
                为 1 时，返回用于读取的终端名 (stdin)。Unix 上，两者有相同的名
                字。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_gettty()</code>
<code class="example"></code>
<code class="example"></code>
term_list()                                             <b class="vimtag"> <a name="term_list()">term_list()</a> </b>
                返回所有终端窗口的缓冲区号的列表。

term_scrape(<code class="special">{buf}</code>, <code class="special">{row}</code>)                               <b class="vimtag"> <a name="term_scrape()">term_scrape()</a> </b>
                获取终端 <code class="special">{buf}</code> 屏幕第 <code class="special">{row}</code> 行的内容。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                首行的 <code class="special">{row}</code> 行为一。<code class="special">{row}</code> 为 "." 时使用光标所在行。<code class="special">{row}</code> 非法
                时返回空串 (<code class="vim">译者注</code>: 应为空列表)。

                返回对应每个屏幕单元格的字典的列表:
                    "chars"     该单元格上的字符 (可有多个)
                    "fg"        前景色，形如 #rrggbb
                    "bg"        背景色，形如 #rrggbb
                    "attr"      单元格的属性，可用  <a href="terminal.html#term_getattr()">term_getattr()</a>  获取个别
                                标志位
                    "width"     单元格宽度: 1 或 2
                双宽单元格只对应一个项目，这意味着列表长度可能小于终端的宽度。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_scrape(row)</code>
<code class="example"></code>
<code class="example"></code>
term_sendkeys(<code class="special">{buf}</code>, <code class="special">{keys}</code>)                            <b class="vimtag"> <a name="term_sendkeys()">term_sendkeys()</a> </b>
                发送键击序列 <code class="special">{keys}</code> 给终端 <code class="special">{buf}</code>。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。

                <code class="special">{keys}</code> 作为键击序列进行翻译。例如，"\<code class="special">&lt;c-x&gt;</code>" 代表 <code class="keystroke">CTRL-X</code> 字符。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_sendkeys(keys)</code>
<code class="example"></code>
<code class="example"></code>
term_setansicolors(<code class="special">{buf}</code>, <code class="special">{colors}</code>)                     <b class="vimtag"> <a name="term_setansicolors()">term_setansicolors()</a> </b>
                设置终端 <code class="special">{buf}</code> 使用的 ANSI 颜色调色板。
                <code class="special">{colors}</code> 必须是 16 种合法的色彩名或十六进制色彩代码的列表，如
                同  <a href="syntax.html#highlight-guifg">highlight-guifg</a>  接受的格式一样。
                另见  <a href="terminal.html#term_getansicolors()">term_getansicolors()</a>  和  <a href="terminal.html#g:terminal_ansi_colors">g:terminal_ansi_colors</a> 。

                这些颜色通常是:
                        0    black
                        1    dark red
                        2    dark green
                        3    brown
                        4    dark blue
                        5    dark magenta
                        6    dark cyan
                        7    light grey
                        8    dark grey
                        9    red
                        10   green
                        11   yellow
                        12   blue
                        13   magenta
                        14   cyan
                        15   white

                在 GUI 和 <a href="options.html#'termguicolors'">'termguicolors'</a> 置位时在终端上使用这些颜色。如果不使
                用 GUI 颜色 (GUI 模式或 <a href="options.html#'termguicolors'">'termguicolors'</a>)，终端窗口总是使用下层
                终端的 16 种 ANSI 颜色。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_setansicolors(colors)</code>
<code class="example"></code>
                <code class="notvi">{仅当编译时打开 GUI 和/或  <a href="various.html#+termguicolors">+termguicolors</a>  特性时才有效}</code>


term_setapi(<code class="special">{buf}</code>, <code class="special">{expr}</code>)                              <b class="vimtag"> <a name="term_setapi()">term_setapi()</a> </b>
                设置终端 <code class="special">{buf}</code> 中的  <a href="terminal.html#terminal-api">terminal-api</a>  函数使用的函数名前缀。
                例如: 
<code class="example">                    :call term_setapi(buf, "Myapi_")</code>
<code class="example">                    :call term_setapi(buf, "")</code>

                缺省是 "Tapi_"。<code class="special">{expr}</code> 为空串时 <code class="special">{buf}</code> 不能使用  <a href="terminal.html#terminal-api">terminal-api</a> 
                函数。

                也可用作  <a href="eval.html#method">method</a> ，基用于 <code class="special">{buf}</code>: 
<code class="example">                        GetBufnr()-&gt;term_setapi({expr})</code>
<code class="example"></code>
<code class="example"></code>
term_setkill(<code class="special">{buf}</code>, <code class="special">{how}</code>)                              <b class="vimtag"> <a name="term_setkill()">term_setkill()</a> </b>
                退出 Vim 或用其它方式试图关闭终端窗口时，<code class="special">{how}</code> 定义终端中的作
                业是否被中止。
                若 <code class="special">{how}</code> 为空 (缺省)，不中止作业。退出尝试会生成  <a href="terminal.html#E947">E947</a> 。
                否则，<code class="special">{how}</code> 指定发送给作业的信号。 <a href="channel.html#job_stop()">job_stop()</a>  说明可选的值。

                发送信号后 Vim 等待不多于一秒的时间来检查作业是否确实中止。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_setkill(how)</code>
<code class="example"></code>
<code class="example"></code>
term_setrestore(<code class="special">{buf}</code>, <code class="special">{command}</code>)                       <b class="vimtag"> <a name="term_setrestore()">term_setrestore()</a> </b>
                设置写在会活文件中以恢复终端中的作业的命令。会话文件中写入的行
                是: 
<code class="example">                        terminal ++curwin ++cols=%d ++rows=%d {command}</code>
                要确保对命令适当地转义。

                使用空 <code class="special">{command}</code> 来执行 <a href="options.html#'shell'">'shell'</a>。
                使用 "NONE" 来不从此窗口恢复。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_setrestore(command)</code>
<code class="example"></code>
<code class="example"></code>
term_setsize(<code class="special">{buf}</code>, <code class="special">{rows}</code>, <code class="special">{cols}</code>)             <b class="vimtag"> <a name="term_setsize()">term_setsize()</a> </b> <b class="vimtag"> <a name="E955">E955</a> </b>
                设置终端 <code class="special">{buf}</code> 的大小。如果可能，包含终端的窗口的尺寸也会跟着
                调整。如果 <code class="special">{rows}</code> 或 <code class="special">{cols}</code> 为零或负，大小不改变。

                <code class="special">{buf}</code> 必须是对应终端窗口的缓冲区号。空串代表当前缓冲区。如果该
                缓冲区不存在或不是终端窗口，报错。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_setsize(rows, cols)</code>
<code class="example"></code>
<code class="example"></code>
term_start(<code class="special">{cmd}</code> [, <code class="special">{options}</code>])                 <b class="vimtag"> <a name="term_start()">term_start()</a> </b>
                打开终端窗口并在其中运行 <code class="special">{cmd}</code>。

                类似于  <a href="channel.html#job_start()">job_start()</a> ，<code class="special">{cmd}</code> 可以是字符串或者列表。字符串
                "NONE" 可用来打开终端窗口而不启动作业，终端的 pty 可用于 gdb
                这样的命令。

                返回终端窗口的缓冲区号。如果不能执行 <code class="special">{cmd}</code>，仍打开窗口并显示错
                误信息。
                如果打开窗口失败，返回零。

                <code class="special">{options}</code> 和用于  <a href="channel.html#job_start()">job_start()</a>  的选项类似，见  <a href="channel.html#job-options">job-options</a> 。
                不过，不是所有的选项都可用。以下是支持的选项:
                   所有超时选项
                   "stoponexit"、"cwd"、"env"
                   "callback"、"out_cb"、"err_cb"、"exit_cb"、"close_cb"
                   "in_io"、"in_top"、"in_bot"、"in_name"、"in_buf"
                   "out_io"、"out_name"、"out_buf"、"out_modifiable"、"out_msg"
                   "err_io"、"err_name"、"err_buf"、"err_modifiable"、"err_msg"
                不过，至少 stdin、stdout 或 stderr 其中之一必须连接到终端上。
                I/O 和终端连接时，不使用该部分的回调函数。

                以下是额外的选项:
                   "term_name"       缓冲区名，缺省是命令名。
                   "term_rows"       终端使用的垂直尺寸，缺省是
                                     <a href="options.html#'termwinsize'">'termwinsize'</a>；合法范围是零到 1000
                   "term_cols"       终端使用的水平尺寸，缺省是 <a href="options.html#'termwinsize'">'termwinsize'</a>
                   "vertical"        垂直分割窗口；<code class="note">备注</code> 另一窗口位置可用命令行
                                     修饰符来定义，如  <a href="windows.html#:belowright">:belowright</a> 。
                   "curwin"          使用当前窗口，不分割窗口；如果不能
                                      <a href="editing.html#abandon">abandon</a>  当前缓冲区，则报错
                   "hidden"          不打开窗口
                   "norestore"       不把终端窗口加入到会话文件中
                   "term_kill"       试图关闭终端应如何操作，见
                                      <a href="terminal.html#term_setkill()">term_setkill()</a> 
                   "term_finish"     作业结束时的行为:
                                        "close": 关闭任何窗口
                                        "open": 有必要时打开窗口
                                     <code class="note">注意</code> "open" 可能会打断你的操作。
                                     见  <a href="terminal.html#term++close">term++close</a>  和  <a href="terminal.html#term++open">term++open</a> 。
                   "term_opencmd"    "term_finish" 用 "open" 时打开窗口所用的
                                     命令；必须包含 "%d"，放在需要缓冲区号的位
                                     置上，如 "10split|buffer %d"；缺省是
                                     "botright sbuf %d"
                   "term_highlight"  代替 "Terminal" 的高亮组名
                   "eof_chars"       发送完缓冲区的所有行后写入终端的文本。缺
                                     省在 MS-Windows 上是 <code class="keystroke">CTRL-D</code>，Python 使用
                                     <code class="keystroke">CTRL-Z</code> 或 "exit()"。外壳使用 "exit"。总会
                                     加上 CR。
                   "ansi_colors"     定义用于 GUI 色彩模式的 ANSI 调色板的十六
                                     种色彩名或十六进代码的列表。见
                                      <a href="terminal.html#g:terminal_ansi_colors">g:terminal_ansi_colors</a> 。
                   "tty_type"        (仅用于 MS-Windows): 指定使用的 pty。
                                     <a href="options.html#'termwintype'">'termwintype'</a> 说明可用的值。
                   "term_api"         <a href="terminal.html#terminal-api">terminal-api</a>  函数的函数名前缀。见
                                      <a href="terminal.html#term_setapi()">term_setapi()</a> 。

                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetCommand()-&gt;term_start()</code>
<code class="example"></code>
<code class="example"></code>
term_wait(<code class="special">{buf}</code> [, <code class="special">{time}</code>])                                     <b class="vimtag"> <a name="term_wait()">term_wait()</a> </b>
                等待 <code class="special">{buf}</code> 未处理的更新。
                <code class="special">{buf}</code> 的用法见  <a href="terminal.html#term_getsize()">term_getsize()</a> 。
                <code class="special">{time}</code> 是等待更新到达以毫秒计的时间。未指定则使用 10 毫秒。
                也可用作  <a href="eval.html#method">method</a> : 
<code class="example">                        GetBufnr()-&gt;term_wait()</code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>3. 终端通信                                      <b class="vimtag"> <a name="terminal-communication">terminal-communication</a> </b></h4>
有几种和终端中运行的作业通信的办法:
- 使用  <a href="terminal.html#term_sendkeys()">term_sendkeys()</a>  从 Vim 发送文本和转义序列到作业。
- 使用 JSON API 从作业发送经编码的命令到 Vim。
- 使用  <a href="remote.html#client-server">client-server</a>  机制。适用于有 X server 和 MS-Windows 的机器。


<code class="section">Vim 到 job: term_sendkeys() </code>
                                                        <b class="vimtag"> <a name="terminal-to-job">terminal-to-job</a> </b>
这允许运程控制在终端中运行的作业。这是单向的机制。但作业可以刷新显示给 Vim 传
递信号。例如，如果终端中运行的是外壳，可以这样: 
<code class="example">        call term_sendkeys(buf, "ls *.java\&lt;CR&gt;")</code>
<code class="example"></code>
这需要作业处于正确的状态，以便接收键击时，可以作出正确的反应。在上例中，外壳必
须正在等待命令行的键入。

如果作业支持，可以反方向发送 JSON API 转义序列，如: 
<code class="example">        call term_sendkeys(buf, "\&lt;Esc&gt;]51;["response"]\x07")</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">Job 到 Vim: JSON API </code>
                                                        <b class="vimtag"> <a name="terminal-api">terminal-api</a> </b>
作业可以使用特殊的转义序列发送 JSON 给 Vi。JSON 编码一个 Vim 能理解的命令。一
个这样信息的示例: 
<code class="example">        &lt;Esc&gt;]51;["drop", "README.md"]&lt;07&gt;</code>
<code class="example"></code>
本体总是列表，以便寻找结尾处: ]<code class="special">&lt;07&gt;</code>。
<code class="special">&lt;Esc&gt;</code>]51;msg<code class="special">&lt;07&gt;</code> 序列是 xterm 保留给 "Emacs shell" 的，和我们要做的差不多吧。

目前支持的命令:

        call <code class="special">{funcname}</code> <code class="special">{argument}</code>

                调用用户定义函数并带参数 <code class="special">{argument}</code>。
                函数调用时有两个参数: 终端缓冲区号和 <code class="special">{argument}</code>，一个解码的
                JSON 参数。
                缺省，函数名必须以 "Tapi_" 开始，以免不小心调用了为非终端 API
                设计的函数。可用  <a href="terminal.html#term_setapi()">term_setapi()</a>  改变。
                用户函数须检查参数的合法性。
                函数可以用  <a href="terminal.html#term_sendkeys()">term_sendkeys()</a>  来发送反馈。
                JSON 示例: 
<code class="example">                        ["call", "Tapi_Impression", ["play", 14]]</code>
                会调用以下定义的函数: 
<code class="example">                        function Tapi_Impression(bufnum, arglist)</code>
<code class="example">                          if len(a:arglist) == 2</code>
<code class="example">                            echomsg "impression " .. a:arglist[0]</code>
<code class="example">                            echomsg "count " .. a:arglist[1]</code>
<code class="example">                          endif</code>
<code class="example">                        endfunc</code>
                如果用  <a href="eval.html#:echo">:echo</a> ，重画可能被删除其输出，用  <a href="eval.html#:echomsg">:echomsg</a>  就会保证在
                 <a href="message.html#:messages">:messages</a>  中看到这些消息。

        drop <code class="special">{filename}</code> <code class="special">[options]</code>

                让 Vim 打开文件，就像  <a href="windows.html#:drop">:drop</a>  命令那样。如果 <code class="special">{filename}</code> 已经在
                窗口中打开，切换到该窗口。否则打开新窗口，并编辑 <code class="special">{filename}</code>。
                <code class="note">注意</code> 作业和 Vim 都可能改变当前目录，所以最好使用完整路径。

                <code class="special">[options]</code> 只在打开新窗口里有用。如果给出，必须是字典。和
                 <a href="editing.html#++opt">++opt</a>  类似，识别以下项目:
                  "ff"          文件格式: "dos"、"mac" 或 "unix"
                  "fileformat"  同上
                  "enc"         覆盖 <a href="options.html#'fileencoding'">'fileencoding'</a>
                  "encoding"    同上
                  "bin"         置位 <a href="options.html#'binary'">'binary'</a>
                  "binary"      同上
                  "nobin"       复位 <a href="options.html#'binary'">'binary'</a>
                  "nobinary"    同上
                  "bad"         指定坏字符的行为，见  <a href="editing.html#++bad">++bad</a> 

                JSON 示例: 
<code class="example">                        ["drop", "path/file.txt", {"ff": "dos"}]</code>
<code class="example"></code>
让 vim 发送此转义序列的一个小技巧: 
<code class="example">        exe "set t_ts=\&lt;Esc&gt;]51; t_fs=\x07"</code>
<code class="example">        let &amp;titlestring = '["call","Tapi_TryThis",["hello",123]]'</code>
<code class="example">        redraw</code>
<code class="example">        set t_ts&amp; t_fs&amp;</code>
<code class="example"></code>
理据: 为什么不允许任何命令或表达式呢？因为可能会造成安全问题。
                                                <b class="vimtag"> <a name="terminal-autoshelldir">terminal-autoshelldir</a> </b>
以下代码可用于从外壳把当前目录传递给 Vim。
在 .vimrc 里: 
<code class="example">        def g:Tapi_lcd(_, path: string)</code>
<code class="example">            if isdirectory(path)</code>
<code class="example">                execute 'silent lcd ' .. fnameescape(path)</code>
<code class="example">            endif</code>
<code class="example">        enddef</code>

同时，bash 初始文件里: 
<code class="example">        if [[ -n "$VIM_TERMINAL" ]]; then</code>
<code class="example">            PROMPT_COMMAND='_vim_sync_PWD'</code>
<code class="example">            function _vim_sync_PWD() {</code>
<code class="example">              printf '\033]51;["call", "Tapi_lcd", "%q"]\007' "$PWD"</code>
<code class="example">            }</code>
<code class="example">        fi</code>

或者，用于 zsh: 
<code class="example">        if [[ -n "$VIM_TERMINAL" ]]; then</code>
<code class="example">            autoload -Uz add-zsh-hook</code>
<code class="example">            add-zsh-hook -Uz chpwd _vim_sync_PWD</code>
<code class="example">            function _vim_sync_PWD() {</code>
<code class="example">                printf '\033]51;["call", "Tapi_lcd", "%q"]\007' "$PWD"</code>
<code class="example">            }</code>
<code class="example">        fi</code>

或者，用于 fish: 
<code class="example">        if test -n "$VIM_TERMINAL"</code>
<code class="example">            function _vim_sync_PWD --on-variable=PWD</code>
<code class="example">                printf '\033]51;["call", "Tapi_lcd", "%s"]\007' "$PWD"</code>
<code class="example">            end</code>
<code class="example">        end</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">使用客户-服务器特性 </code>
                                                <b class="vimtag"> <a name="terminal-client-server">terminal-client-server</a> </b>
只在 v:servername 非空时有用。如果需要可以这样在打开终端前设置之: 
<code class="example">        call remote_startserver('vim-server')</code>
<code class="example"></code>
在终端里，$VIM_SERVERNAME 会设为传递进来的服务器名。

在作业中可以这样做: 
<code class="example">        vim --servername $VIM_SERVERNAME --remote +123 some_file.c</code>
这会打开文件 "some_file.c" 并把光标放在第 123 行上。

</section><hr class="doubleline" /><section class=inner>
<h4>4. 远程测试                                             <b class="vimtag"> <a name="terminal-testing">terminal-testing</a> </b></h4>
多数 Vim 测试在 Vim 内部执行脚本。有些测试这样不行，因为测试的执行和要测试的代
码有干扰。为了避免这种干扰，可在终端窗口中执行 Vim。测试给它发送键击并检视结果
的屏幕状态。

<code class="section">函数 </code>

 <a href="terminal.html#term_sendkeys()">term_sendkeys()</a>        给终端发送键击 (不应用映射)
 <a href="terminal.html#term_wait()">term_wait()</a>            等待屏幕的刷新
 <a href="terminal.html#term_scrape()">term_scrape()</a>          检视终端屏幕


</section><hr class="doubleline" /><section class=inner>
<h4>5. 屏幕截图比较                                         <b class="vimtag"> <a name="terminal-diff">terminal-diff</a> </b></h4>
有些情况下要测试 Vim 在屏幕上是否显示正确的字符很麻烦，例如带语法高亮的时候。
现在有一个略简便的方法，为终端进行屏幕截图，并和期待的屏幕截图相比较。

Vim 使用实际显示窗口的大小、文本、颜色和其它属性。Vim 的屏幕大小、字体和其它属
性是无关的。这样此机制在系统间可移植。而常规的屏幕截图会反映所有的差异，包括字
体大小和家族等。


<code class="section">编写 Vim 屏幕截图测试 </code>
                                                        <b class="vimtag"> <a name="terminal-dumptest">terminal-dumptest</a> </b>
一个实际的例子可见 src/testdir/test_syntax.vim 中的 Test_syntax_c() 函数。其主
要步骤是:
- 写一个待测试的文件。用于测试语法高亮。也可以从空缓冲区启动 Vim。
- 在指定大小的终端中运行 Vim。缺省是 20 行每行 75 字符。这保证截图有恒定的大
  小。 函数 RunVimInTerminal() 会做到这一点。把 Vim 命令的参数传递给它就可以
  了。
- 用  <a href="terminal.html#term_sendkeys()">term_sendkeys()</a>  给 Vim 发送任何命令。例如: 
<code class="example">        call term_sendkeys(buf, ":echo &amp;lines &amp;columns\&lt;CR&gt;")</code>
- 用 VerifyScreenDump() 检查屏幕现在匹配期待的状态。它假定参考屏幕截图在
  src/testdir/dumps/ 目录下，名字不需要 ".dump" 部分。建议使用测试函数的名字加
  一个序列号，以便我们知道什么测试使用此文件。
- 重复发送命令和检查状态的步骤。
- 最后调用 StopVimInTerminal() 来停止 Vim。

第一次你还没有屏幕截图。先建立空文件，如: 
<code class="example">        touch src/testdir/dumps/Test_function_name_01.dump</code>
<code class="example"></code>
此时测试会失败，并给出比较参考截图和失败截图的命令，如: 
<code class="example">        call term_dumpdiff("failed/Test_func.dump", "dumps/Test_func.dump")</code>
<code class="example"></code>
把当前目录设为 src/testdir，在 Vim 中使用此命令。一旦你对测试满意了，把失败截
图移动到参考截图的位置: 
<code class="example">        :!mv failed/Test_func.dump dumps/Test_func.dump</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">创建屏幕截图 </code>
                                                        <b class="vimtag"> <a name="terminal-screendump">terminal-screendump</a> </b>
要创建屏幕截图，在终端中运行 Vim (或其它程序)，并使它显示想要的状态。然后用
 <a href="terminal.html#term_dumpwrite()">term_dumpwrite()</a>  函数来创建屏幕截图文件。例如: 
<code class="example">        :call term_dumpwrite(77, "mysyntax.dump")</code>
<code class="example"></code>
这里 "77" 是终端缓冲区号。 <code class="badlink">:ls!</code>  可以看到。

要浏览屏幕截图，可用  <a href="terminal.html#term_dumpload()">term_dumpload()</a> : 
<code class="example">        :call term_dumpload("mysyntax.dump")</code>
<code class="example"></code>
要验证 Vim 还显示完全相同的屏幕，一模一样地再运行一次 Vim，显示想要的状态。然
后用另一个文件名再创建一份屏幕截图: 
<code class="example">        :call term_dumpwrite(88, "test.dump")</code>
<code class="example"></code>
要断言两份文件完全相同，可用  <a href="testing.html#assert_equalfile()">assert_equalfile()</a> : 
<code class="example">        call assert_equalfile("mysyntax.dump", "test.dump")</code>
<code class="example"></code>
如果有不同，v:errors 会包含错误信息。


<code class="section">比较屏幕截图 </code>
                                                <b class="vimtag"> <a name="terminal-diffscreendump">terminal-diffscreendump</a> </b>
 <a href="testing.html#assert_equalfile()">assert_equalfile()</a>  不能方便地看到差异之处。要发现问题，可用
 <a href="terminal.html#term_dumpdiff()">term_dumpdiff()</a> : 
<code class="example">        call term_dumpdiff("mysyntax.dump", "test.dump")</code>
<code class="example"></code>
这会打开一个窗口，包含三个部分:
1.  第一份截图的内容
2.  两份截图的差异
3.  第二份截图的内容

你通常在第二部分看到差异之处。<a href="options.html#'ruler'">'ruler'</a> 可用来把它和第一份或第二份截图的位置联系
起来。以下字母指示区别的类型:
        X       不同字符
        &gt;       光标在第一份但不在第二份
        &lt;       光标在第二份但不在第一份
        w       不同字符宽度 (单宽度对双宽度)
        f       不同前景色
        b       不同背景色
        a       不同属性 (粗体、下划线、反显等等)
        ?       两者都缺少的字符
        +       第一份缺少的字符
        -       第二份缺少的字符

另外，按 "s" 会交换两份截图。多做几次，在文本的上下文中找到差异会容易一些。

</section><hr class="doubleline" /><section class=inner>
<h4>6. 调试                                 <b class="vimtag"> <a name="terminal-debug">terminal-debug</a> </b> <b class="vimtag"> <a name="terminal-debugger">terminal-debugger</a> </b></h4>
终端调试插件可用来使用 gdb 来调试程序而同时在 Vim 窗口中查看源代码。因为这完全
包含在 Vim 内完成，我们通过 ssh 连接也可以远程进行工作。

如果没有  <a href="various.html#+terminal">+terminal</a>  特性但可能的话，此插件会使用 "prompt" 缓冲区类型。详见下
述的  <a href="terminal.html#termdebug-prompt">termdebug-prompt</a> 。


<code class="section">启动 </code>
                                                        <b class="vimtag"> <a name="termdebug-starting">termdebug-starting</a> </b>
此命令载入插件: 
<code class="example">        packadd termdebug</code>
                                                        <b class="vimtag"> <a name=":Termdebug">:Termdebug</a> </b>
要启动调试，用  <a href="terminal.html#:Termdebug">:Termdebug</a>  或  <a href="terminal.html#:TermdebugCommand">:TermdebugCommand</a>  后跟命令名，如: 
<code class="example">        :Termdebug vim</code>
<code class="example"></code>
这会打开两个窗口:

gdb 窗口        终端窗口，其中执行 "gdb vim"。这里你可以直接和 gdb 交互。缓冲
                区名是 "!gdb"。

program 窗口    用于执行程序的终端窗口，。gdb 里 "run" 时，程序 I/O 会在此窗口
                中发生，这样不会和控制的 gdb 有干扰。
                缓冲区名是 "debugged program"。

当前窗口用于显示源代码。gdb 暂停时，如有可能会显示源代码的位置。标号用来高亮当
前位置，使用高亮组 debugPC。

如果当前窗口缓冲区被修改，会打开另一个窗口来显示 gdb 的当前位置。用  <a href="terminal.html#:Winbar">:Winbar</a> 
可以在那里加上窗口工具条。

聚焦执行程序的终端可以和它互动。这和终端窗口运行任何命令的用法一样。

通常在 gdb 窗口中输入 "quit" 可以结束调试器。此时，这两个打开的窗口会被关闭。

一次只能激活一个调试器。
                                                        <b class="vimtag"> <a name=":TermdebugCommand">:TermdebugCommand</a> </b>
要指定要调试的命令，可用  <a href="terminal.html#:TermdebugCommand">:TermdebugCommand</a>  命令后跟命令名和其它参数。 
<code class="example">        :TermdebugCommand vim --clean -c ':set nu'</code>
<code class="example"></code>
 <a href="terminal.html#:Termdebug">:Termdebug</a>  和  <a href="terminal.html#:TermdebugCommand">:TermdebugCommand</a>  两者都支持可选的 "!" 感叹号参数，它会立即
启动命令而不在 gdb 窗口中暂停 (光标会留在待调试的窗口)。示例: 
<code class="example">        :TermdebugCommand! vim --clean</code>
<code class="example"></code>
要把 gdb 和已经在运行的可执行程序或 core 文件绑定，传递额外的参数。如: 
<code class="example">        :Termdebug vim core</code>
<code class="example">        :Termdebug vim 98343</code>
<code class="example"></code>
如果不给出参数，会打开 gdb 窗口，那里要通过如 gdb  <code class="badlink">file</code>  命令等方式去执行想要
的命令。


<code class="section">示例会话 </code>
                                                        <b class="vimtag"> <a name="termdebug-example">termdebug-example</a> </b>
从 Vim  "src" 目录开始并编译 Vim: 
<code class="example">        % make</code>
确保有调试符号，通常这意味着 $CFLAGS 应包含 "-g"。

启动 Vim: 
<code class="example">        % ./vim</code>
载入 termdebug 插件并开始调试 Vim: 
<code class="example">        :packadd termdebug</code>
<code class="example">        :Termdebug vim</code>
你现在应有三个窗口:
    源代码  - 你开始的地方，有带按钮的窗口工具条
    gdb     - 这里你开始输入 gdb 命令
    program - 执行中程序会使用本窗口

可用 <code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-W</code> 或鼠标在窗口间转换焦点。把焦点放在 gdb 窗口上并输入: 
<code class="example">        break ex_help</code>
<code class="example">        run</code>
Vim 会在 program 窗口上开始运行。把焦点放在那里并输入: 
<code class="example">        :help gui</code>
Gdb 会在 ex_help 断点处运行。源代码窗口此时会显示 ex_cmds.c 文件。一个红色的
"1 " 标记会出现在标号列里，指示断点所在的位置。调试器所在的行被高亮。现在你可
以在程序中步进了。让我们用下鼠标: 在窗口工具条的 "Next" 按钮上点击。你会看到随
着调试器执行一行源代码，高亮也跟着移动。

点击 "Next" 几次直到 for 循环被高亮。把光标放在 "eap-&gt;arg" 的尾部，然后按工具
条上的 "Eval"。你会看到:
<code class="section">        "eap-&gt;arg": 0x555555e68855 "gui" </code>
这样你可以检视局部变量的值。也可以聚焦在 gdb 窗口上并使用 "print" 命令，如: 
<code class="example">        print *eap</code>
如果支持鼠标指针移动，Vim 也会在鼠标停留的文本上显示通过 gdb 计算的气泡。

现在回到源代码窗口，把光标放在 for 循环后的第一行，然后输入: 
<code class="example">        :Break</code>
你会看到 "&gt;&gt;" 标记出现，指示一个新的断点。现在在工具条上点击 "Cont"，这会继续
执行代码直到断点为止。

gdb 窗口上可以输入更高级的命令。例如，输入: 
<code class="example">        watch curbuf</code>
现在在工具条点击 "Cont" (或在 gdb 窗口中输入 "cont")。现在会继续执行直到
"curbuf" 的值有改变，这应在 do_ecmd() 里。
要删除此观察点，在 gdb 窗口中再输入: 
<code class="example">        delete 3</code>
<code class="example"></code>
要看到堆栈，在gdb 窗口中输入: 
<code class="example">        where</code>
在堆栈框架间移动，比如可用: 
<code class="example">        frame 3</code>
源代码窗口会显示在更深层的调用所在的代码。


<code class="section">代码中步进 </code>
                                                        <b class="vimtag"> <a name="termdebug-stepping">termdebug-stepping</a> </b>
把焦点移到 gdb 窗口，在那里输入命令。常用的有:
- <code class="keystroke">CTRL-C</code>        中断程序
- next          执行当前行并停在下一行
- step          执行当前行并停在下个语句上，进入函数
- until         执行直到跨过当前光标行或跨过指定位置或当前堆栈框架返回为止
- finish        执行直到退出当前函数为止
- where         显示堆栈
- frame N       转到第 N 堆栈框架
- continue      继续执行

                                                <b class="vimtag"> <a name=":Run">:Run</a> </b> <b class="vimtag"> <a name=":Arguments">:Arguments</a> </b>
在显示源代码的窗口中以下命令可用于控制 gdb:
  <a href="terminal.html#:Run">:Run</a>  <code class="special">[args]</code>      执行程序，使用 <code class="special">[args]</code> 或之前的参数
  <a href="terminal.html#:Arguments">:Arguments</a>  <code class="special">{args}</code>  设置下次  <a href="terminal.html#:Run">:Run</a>  使用的参数

 <b class="vimtag"> <a name=":Break">:Break</a> </b>       在光标位置设置断点
 :Break <code class="special">{position}</code>
                在指定位置设置断点
 <b class="vimtag"> <a name=":Clear">:Clear</a> </b>       删除光标位置所在的断点

 <b class="vimtag"> <a name=":Step">:Step</a> </b>        执行 gdb "step" 命令
 <b class="vimtag"> <a name=":Over">:Over</a> </b>        执行 gdb "next" 命令 ( <a href="editing.html#:Next">:Next</a>  是 Vim 的命令)
 <b class="vimtag"> <a name=":Until">:Until</a> </b>       执行 gdb "until" 命令
 <b class="vimtag"> <a name=":Finish">:Finish</a> </b>      执行 gdb "finish" 命令
 <b class="vimtag"> <a name=":Continue">:Continue</a> </b>    执行 gdb "continue" 命令
 <b class="vimtag"> <a name=":Stop">:Stop</a> </b>        中断程序

如果设置了 <a href="options.html#'mouse'">'mouse'</a>，插件加入窗口工具条，带以下项目:
  Step           <a href="terminal.html#:Step">:Step</a> 
  Next           <a href="terminal.html#:Over">:Over</a> 
  Finish         <a href="terminal.html#:Finish">:Finish</a> 
  Cont           <a href="terminal.html#:Continue">:Continue</a> 
  Stop           <a href="terminal.html#:Stop">:Stop</a> 
  Eval           <a href="terminal.html#:Evaluate">:Evaluate</a> 
这样你就可用鼠标完成大部分的常用操作。需要设置 <a href="options.html#'mouse'">'mouse'</a> 选项来支持鼠标点击。
如何配置此工具条可见  <a href="terminal.html#termdebug_winbar">termdebug_winbar</a> 。
                                                                <b class="vimtag"> <a name=":Winbar">:Winbar</a> </b>
你可以这样在其它打开的窗口加入窗口工具条: 
<code class="example">  :Winbar</code>
<code class="example"></code>
如果 gdb 停在某个源代码行上而当前没有窗口显示该源代码，会创建新窗口来显示该源
代码。如果源代码窗口的缓冲区被修改而不能放弃，这也会发生。

gdb 为每个断点编号。Vim 里在标号列中以红色背景显示该编号。可以使用这些 gdb 命
令:
- info break    列出断点
- delete N      删除断点 N
如果光标在断点行上，也可用  <a href="terminal.html#:Clear">:Clear</a>  命令，或右键菜单项目中的 "Clear
breakpoint"。


<code class="section">检视变量 </code>
                                        <b class="vimtag"> <a name="termdebug-variables">termdebug-variables</a> </b> <b class="vimtag"> <a name=":Evaluate">:Evaluate</a> </b>
  <a href="terminal.html#:Evaluate">:Evaluate</a>         检视光标下的表达式
  <a href="various.html#K">K</a>                 同上 (要关闭之，见  <a href="terminal.html#termdebug_map_K">termdebug_map_K</a> )
  <a href="terminal.html#:Evaluate">:Evaluate</a>  <code class="special">{expr}</code>   计算 <code class="special">{expr}</code>
  <code class="badlink">:'&lt;,'&gt;Evaluate</code>      计算可视选择的文本

类似于在 gdb 窗口用 "print"。
通常可缩短  <a href="terminal.html#:Evaluate">:Evaluate</a>  为  <code class="badlink">:Ev</code> 。


<code class="section">其它命令 </code>
                                                        <b class="vimtag"> <a name="termdebug-commands">termdebug-commands</a> </b>
 <b class="vimtag"> <a name=":Gdb">:Gdb</a> </b>      跳转到 gdb 窗口
 <b class="vimtag"> <a name=":Program">:Program</a> </b>    跳转到运行程序的窗口
 <b class="vimtag"> <a name=":Source">:Source</a> </b>     跳转到源代码窗口，如果还没有则创建之
 <b class="vimtag"> <a name=":Asm">:Asm</a> </b>      跳转到反汇编窗口，如果还没有则创建之

<code class="section">事件 </code>
                                                        <b class="vimtag"> <a name="termdebug-events">termdebug-events</a> </b>
可用四个自动命令: 
<code class="example">        au User TermdebugStartPre  echomsg '调试启动中'</code>
<code class="example">        au User TermdebugStartPost echomsg '调试已开始'</code>
<code class="example">        au User TermdebugStopPre   echomsg '调试中止中'</code>
<code class="example">        au User TermdebugStopPost  echomsg '调试已中止'</code>

                                                <b class="vimtag"> <a name="TermdebugStartPre">TermdebugStartPre</a> </b>
TermdebugStartPre               开始调试前。
                                如果调试器已运行或调试器命令不能执行，不触发。
                                                <b class="vimtag"> <a name="TermdebugStartPost">TermdebugStartPost</a> </b>
TermdebugStartPost              调试初始化结束后。
                                给  <a href="terminal.html#:Termdebug">:Termdebug</a>  或  <a href="terminal.html#:TermdebugCommand">:TermdebugCommand</a>  加 "!"
                                感叹号时，此事件在 gdb 运行提供的命令前触发。
                                                <b class="vimtag"> <a name="TermdebugStopPre">TermdebugStopPre</a> </b>
TermdebugStopPre                调试结束前，此时 gdb 已终止，最有可能在 gdb 窗
                                口里输入 "quit" 命令后发生。
                                                <b class="vimtag"> <a name="TermdebugStopPost">TermdebugStopPost</a> </b>
TermdebugStopPost               调试结束后，gdb 相关的窗口已关闭，真正删除了调
                                试缓冲区，恢复了调试之前的状态。


<code class="section">定制 </code>
                                <b class="vimtag"> <a name="termdebug-customizing">termdebug-customizing</a> </b> <b class="vimtag"> <a name="g:termdebug_config">g:termdebug_config</a> </b>
过去配置使用若干全局变量。它们已被废弃，建议使用 g:termdebug_config 字典。如果
g:termdebug_config 存在， <code class="emphasis">不</code> 使用其它的全局变量。
推荐以赋值空字典开始: 
<code class="example">        let g:termdebug_config = {}</code>
<code class="example"></code>
然后就可以像下面那样给字典加入项目。为完整起见下面还是会提到废弃的全局变量名。
要切换到 g:termdebug_config，可以据此找到旧变量名并使用相应的值，然后删除废弃
变量。


<code class="section">提示模式 </code>
                                                <b class="vimtag"> <a name="termdebug-prompt">termdebug-prompt</a> </b>
如果不支持  <a href="various.html#+terminal">+terminal</a>  特性且在 MS-Windows 上，gdb 会在 <a href="options.html#'buftype'">'buftype'</a> 设为
"prompt" 的缓冲区中运行。工作方式略有不同:
- 键入命令时，gdb 窗口会进入插入模式。<code class="special">&lt;Esc&gt;</code> 会进入普通模式，然后你在缓冲区内可
  以移动，复制/粘贴，等等。任何开始插入模式的命令，如  <a href="insert.html#a">a</a>  或  <a href="insert.html#i">i</a> ，会回去进行
  gdb 命令的编辑。
- 待调试的程序在单独的窗口中运行。MS-Windows 上这是个新的控制台窗口。Unix 上，
  如果  <a href="various.html#+terminal">+terminal</a>  特性可用，打开终端窗口以运行待调试的程序。

                                                <b class="vimtag"> <a name="termdebug_use_prompt">termdebug_use_prompt</a> </b>
即使  <a href="various.html#+terminal">+terminal</a>  特性可用，也可使用提示模式，用: 
<code class="example">        let g:termdebug_config['use_prompt'] = 1</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebug_use_prompt = 1</code>

                                                <b class="vimtag"> <a name="termdebug_map_K">termdebug_map_K</a> </b>
K 键通常映射为 :Evaluate。如果不想如此: 
<code class="example">        let g:termdebug_config['map_K'] = 0</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebug_map_K = 0</code>

                                                <b class="vimtag"> <a name="termdebug_disasm_window">termdebug_disasm_window</a> </b>
要缺省显示 Asm 窗口，设置此标志位为 1。
"disarm_window_height" 项目可用于设置窗口高度: 
<code class="example">        let g:termdebug_config['disasm_window'] = 1</code>
<code class="example">        let g:termdebug_config['disasm_window_height'] = 15</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebug_disasm_window = 15</code>
设为任何大于 1 的值时，Asm 窗口会设为此高度。

<code class="section">通信 </code>
                                                <b class="vimtag"> <a name="termdebug-communication">termdebug-communication</a> </b>
还有一个缓冲区，它是隐藏的，用于 Vim 和 gdb 的通信。缓冲区名是 "gdb
communication"。不要删除此缓冲区，否则会破坏调试器。

gdb 有一些奇怪的行为，此插件会尽力而为使其工作。例如，在 gdb 窗口中输入
"continue" 后 <code class="keystroke">CTRL-C</code> 可用于中断运行中的程序。但用 MI 命令 "-exec-continue" 后
<code class="keystroke">CTRL-C</code> 并不中断。因此  <a href="terminal.html#:Continue">:Continue</a>  命令用 "continue" 而不是通信通道。


<code class="section">GDB 命令 </code>
                                                        <b class="vimtag"> <a name="g:termdebugger">g:termdebugger</a> </b>
要改变 gdb 命令的名字，在调用  <a href="terminal.html#:Termdebug">:Termdebug</a>  前设置 g:termdebug_config 的
"debugger" 项目或 "g:termdebugger" 变量: 
<code class="example">        let g:termdebug_config['command'] = "mygdb"</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebugger = "mygdb"</code>
<code class="example"></code>
如果命令需要参数，用列表: 
<code class="example">        let g:termdebug_config['command'] = ['rr', 'replay', '--']</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebugger = ['rr', 'replay', '--']</code>
<code class="example"></code>
会加入若干参数，使 gdb 更适用于调试器功能。要修改这些参数，可提供一个函数以过
滤参数列表: 
<code class="example">        let g:termdebug_config['command_filter'] = MyDebugFilter</code>
<code class="example"></code>
如果不想加入参数，但需要设置 "pty"，可提供一个函数添加必须的参数: 
<code class="example">        let g:termdebug_config['command_add_args'] = MyAddArguments</code>
调用此函数时，首个参数是目前已知的参数列表，第二个参数是 pty 名。
                                                        <b class="vimtag"> <a name="gdb-version">gdb-version</a> </b>
只能用和 gdb 完全兼容的调试器。Vim 使用 GDB/MI 接口。"new-ui" 命令需要 gdb
7.12 或更新的版本。如见此错误:
<code class="section">        Undefined command: "new-ui". Try "help".</code>
你的 gdb 版本太老了。


<code class="section">颜色 </code>
                                        <b class="vimtag"> <a name="hl-debugPC">hl-debugPC</a> </b> <b class="vimtag"> <a name="hl-debugBreakpoint">hl-debugBreakpoint</a> </b>
标号的颜色可用以下高亮组调整:
- debugPC               当前位置
- debugBreakpoint       断点

<a href="options.html#'background'">'background'</a> 为 "light" 的缺省:
  hi debugPC term=reverse ctermbg=lightblue guibg=lightblue
  hi debugBreakpoint term=reverse ctermbg=red guibg=red

<a href="options.html#'background'">'background'</a> 为 "dark" 的缺省:
  hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
  hi debugBreakpoint term=reverse ctermbg=red guibg=red


<code class="section">快捷键 </code>
                                                        <b class="vimtag"> <a name="termdebug_shortcuts">termdebug_shortcuts</a> </b>
可以定义自己的快捷键 (映射) 用 TermDebugSendCommand() 函数来控制 gdb，可在任何
窗口中使用。例如: 
<code class="example">        map ,w :call TermDebugSendCommand('where')&lt;CR&gt;</code>
参数是 gdb 命令。


<code class="section">弹出式菜单 </code>
                                                        <b class="vimtag"> <a name="termdebug_popup">termdebug_popup</a> </b>
缺省 Termdebug 插件设置 <a href="options.html#'mousemodel'">'mousemodel'</a> 为 "popup_setpos"，并在弹出式菜单里加入以
下项目:
        Set breakpoint           <a href="terminal.html#:Break">:Break</a> 
        Clear breakpoint         <a href="terminal.html#:Clear">:Clear</a> 
        Evaluate                 <a href="terminal.html#:Evaluate">:Evaluate</a> 
如果不想要，可以这样关闭之: 
<code class="example">        let g:termdebug_config['popup'] = 0</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebug_popup = 0</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">窗口工具条 </code>
                                                        <b class="vimtag"> <a name="termdebug_winbar">termdebug_winbar</a> </b>
缺省 Termdebug 插件在打开鼠标时创建窗口工具条 (见  <a href="terminal.html#:Winbar">:Winbar</a> )。如果不想要，可以
这样关闭之: 
<code class="example">        let g:termdebug_config['winbar'] = 0</code>
<code class="example"></code>
<code class="example"></code>
<code class="section">Vim 窗口宽度 </code>
                                                        <b class="vimtag"> <a name="termdebug_wide">termdebug_wide</a> </b>
要改变调试开始时的 Vim 窗口宽度并用垂直分割: 
<code class="example">        let g:termdebug_config['wide'] = 163</code>
如果没有 g:termdebug_config，可用: 
<code class="example">        let g:termdebug_wide = 163</code>
<code class="example"></code>
这会在使用  <a href="terminal.html#:Termdebug">:Termdebug</a>  时设置 <a href="options.html#'columns'">'columns'</a> 为 163。退出调试器后此值复原。

如果设置了宽度而 <a href="options.html#'columns'">'columns'</a> 已设为一个更大的值，则使用垂直分割且不改变
<a href="options.html#'columns'">'columns'</a>。

把宽度设为 1 会保证垂直分割且不会改变 <a href="options.html#'columns'">'columns'</a>。这可用于 Vim 不能改变终端大小
的场合。


 vim:tw=78:ts=8:noet:ft=help:norl:

</section>
</article>
<footer>
Generated by vim2html
</footer>
</body>
</html>
